home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / tnftpsr / tmp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-29  |  50.0 KB  |  1,888 lines

  1. /*     ANS compatible Telnet in AES windows     */
  2. /*         compiled with TURBO-C/PURE-C         */
  3. /*  P. Mayer & H. Wieser fortec TU Vienna 1992  */
  4.  
  5. #include <vdi.h>
  6. #include <aes.h>
  7. #include <tos.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "tnftp.h"
  12. #include "tndefs.h"
  13.  
  14. extern char *getmem(long size);
  15. extern int w_open(char *name, int xpos, int ypos, int xsiz, int ysiz, int sliders, int titles, FNT *usefont);
  16. extern void w_closei(struct wi_str *wp);
  17. extern void w_close(struct wi_str *wp);
  18. extern int w_resize(struct wi_str *wp1, int xsiz, int ysiz, int sliders, int titles, int chfont);
  19. extern void w_rename(struct wi_str *wp, char *name);
  20. extern void w_info(struct wi_str *wp, char *name);
  21. extern void w_redraw(struct wi_str *wp, int logic, int xx, int yy, int ww, int hh);
  22. extern void w_update(struct wi_str *wp, int logic, int xx, int yy, int ww, int hh);
  23. extern void w_move(struct wi_str *wp, int xx, int yy, int ww, int hh);
  24. extern void w_top(struct wi_str *wp);
  25. extern void w_bottom(void);
  26. extern void w_hide(void);
  27. extern void w_shrink(struct wi_str *wp);
  28. extern void w_full(struct wi_str *wp);
  29. extern void w_arrow(struct wi_str *wp, int arrow);
  30. extern void w_slide(struct wi_str *wp, int hor, int val);
  31. extern void sethslide(struct wi_str *wp);
  32. extern void w_output(struct wi_str *wp, unsigned char *ptr, short charcount);
  33. extern void lineerase(register struct wi_str *wp, int first, int last);
  34. extern int tcp_out(int tcp_id, char *o_str, int o_len);
  35. extern int do_multi(int);
  36.  
  37. void setvslide(struct wi_str *wp);
  38. void w_flash(struct wi_str *wp, int state);
  39. void scrollup(register struct wi_str *wp, int first, int nlines, int amount);
  40. void scrolldn(register struct wi_str *wp, int first, int nlines, int amount);
  41. int rc_intersect( GRECT *r1, GRECT *r2 );
  42. void vt100_reset (struct wi_str *wp);
  43.  
  44. /* variables used by various routines
  45.  */
  46.  
  47. extern int screen_handle;
  48. extern  long dummy;  /* dummy return variable */
  49. extern    int sdummy;  /* short-sized dummy */
  50.  
  51. extern    int    scr_x, scr_y;  /* size of the screen */
  52. extern    int    scr_w, scr_h;
  53. extern    int    fast;
  54. extern  int    wrap;
  55. /* this makes more updates happen in "scrolled" mode with delayed updates */
  56. extern    int    jerky_updates;
  57. extern    int    mouseflicker;  /* for knowing when to turn it on */
  58. extern    int    audibell;  /* What happens on BEL? */
  59. extern    int    visibell;
  60.  
  61. extern    FNT    *curfont;  /* current font */
  62. extern    WIN_MFDB screen_mf;  /* screen descriptor */
  63. extern    int    mouse;  /* for mouse on/off */
  64.  
  65. extern  struct wi_str *wlist;
  66.  
  67. extern int ncolors;  /* used by ESCb and ESCc */
  68. extern int o_len;
  69. extern char o_str[30];
  70.  
  71. /* the program code... */
  72.  
  73. static BASPAG **oldpd;
  74.  
  75. long set_pd(void)
  76. {
  77.   oldpd = SYSBASE->_run;
  78.   SYSBASE->_run = &_BasPag;
  79.   return 0;
  80. }
  81.  
  82. long restore_pd(void)
  83. {
  84.   SYSBASE->_run = oldpd;
  85.   return 0;
  86. }
  87.  
  88. char *getmem(size)
  89. register long size;
  90. {
  91.   char *got;
  92.  
  93.   /* this relies on malloc taking size_t, and size_t being long, */
  94.   /* or else not compiling with -mshort */
  95.   Supexec(set_pd);
  96.   got = (char *) malloc(size);
  97.   Supexec(restore_pd);
  98.   if (got == NULL) 
  99.   {
  100.     form_alert(1, "[1][Out of memory][ Ok ]");
  101.   }
  102.   else 
  103.   {
  104.     memset(got, 0, size);
  105.   }
  106.   return got;
  107. }
  108.  
  109. /*
  110.  * w_open opens a window with the supplied name.  The new window is
  111.  * top, ergo wlist.  Puts up an alert & returns -1 on errors.
  112.  */
  113.  
  114. int w_open(name, xpos, ypos, xsiz, ysiz, sliders, titles, usefont)
  115. char *name;
  116. int xpos, ypos, xsiz, ysiz;
  117. int sliders, titles;  /* nonzero to get that thing */
  118. FNT *usefont;  /* ptr to font to use */
  119. {
  120.   register struct wi_str *wp;
  121.   int wdes;
  122.   int wtyp;
  123.   int tmp_w, tmp_h; 
  124.  
  125.   wtyp = (sliders ? WI_WITHSLD : 0) | (titles ? WI_WITHTITLE : 0);
  126.   if (ypos < scr_y) ypos = scr_y;
  127.   if (xpos < scr_x) xpos = scr_x;
  128.  
  129.   wind_calc(0, wtyp, 0, 0, usefont->inc_x*xsiz+2*X0,
  130.   usefont->inc_y*ysiz+2*Y0, &sdummy, &sdummy, &tmp_w, &tmp_h);
  131.  
  132.   if (tmp_w>scr_w)
  133.     tmp_w = scr_w;  /* full size <= screen size */
  134.  
  135.   if (tmp_h>scr_h)
  136.     tmp_h = scr_h;
  137.  
  138.   wp = (struct wi_str *)getmem(sizeof(struct wi_str));
  139.   if (wp == NULL) 
  140.   {
  141.     return -1;
  142.   }
  143.  
  144.   wp->wi_mf.wpix = 2*X0 + xsiz*usefont->inc_x;
  145.   wp->wi_mf.hpix = 2*Y0 + ysiz*usefont->inc_y;
  146.   wp->wi_mf.wwords = (wp->wi_mf.wpix>>4) +1;
  147.   wp->wi_mf.planes = 1;
  148.   wp->font = usefont;
  149.   wp->fgbg[1] = 0;  /* foreground color for vrt_copyfm */
  150.   wp->fgbg[0] = 1;  /* background color for vrt_copyfm */
  151.   wp->discard = !wrap;
  152.   wp->recv_flag = 1;
  153.   /* allocate a screen image for this window before wind_create */
  154.   wp->wi_mf.ptr = (short *)getmem(
  155.   ((long)wp->wi_mf.hpix + wp->font->inc_y*MAXSCROLLED) * 
  156.       wp->wi_mf.wwords*2);
  157.  
  158.   if (wp->wi_mf.ptr == NULL) 
  159.   {
  160.     free(wp);
  161.     return -1;
  162.   }
  163.   wdes = wind_create(wtyp, scr_x, scr_y, tmp_w, tmp_h);
  164.   if (wdes < 0) 
  165.   {
  166.     form_alert(1, "[1][Sorry, GEM has|no more windows|for us...][Ok]");
  167.     free(wp->wi_mf.ptr);
  168.     free(wp);
  169.     return -1;
  170.   }
  171.  
  172.   /* install at head of wlist list (which is sorted by window depth) */
  173.   if (wlist == NULL) 
  174.   {
  175.     wp->next = wp->prev = wp;
  176.   }
  177.   else 
  178.   {
  179.     wp->next = wlist;
  180.     wp->prev = wlist->prev;
  181.     wlist->prev->next = wp;
  182.     wlist->prev = wp;
  183.   }
  184.   wlist = wp;
  185.  
  186.   wp->sliders = sliders;
  187.   wp->titles = titles;
  188.   wp->aes_handle = wdes;
  189.   wp->wi_w = X0*2 + usefont->inc_x*xsiz;
  190.   wp->wi_h = Y0*2 + usefont->inc_y*ysiz;
  191.   wp->wi_style = wtyp;
  192.   wp->wi_mainstyle = wtyp;
  193.  
  194.   w_rename(wp, name);
  195.   w_info(wp, "");
  196.  
  197.   if (!fast)
  198.     graf_growbox(0, 0, 20, 10, xpos, ypos, tmp_w, tmp_h);
  199.   wind_open(wdes, xpos, ypos, tmp_w, tmp_h);
  200.   wind_get(wdes, WF_WORKXYWH, &wp->x, &wp->y, &wp->w, &wp->h);
  201.  
  202.   wp->fulled = 0;
  203.   wp->x_off = 0;
  204.   wp->y_off = 0;
  205.   wp->px_off = 0;
  206.   wp->py_off = 0;
  207.   wp->m_off = wp->x & 15;  /* when is this used? */
  208.   wp->cur_x = X0;
  209.   wp->cur_y = Y0;
  210.   wp->top_y = Y0;
  211.   wp->x_chrs = xsiz;
  212.   wp->y_chrs = ysiz;
  213.  
  214.   setvslide(wp);
  215.   sethslide(wp);
  216.   w_redraw(wp,FM_COPY, wp->x, wp->y, wp->w, wp->h);
  217.   vt100_reset(wp);
  218.   wlist->markx1 = wlist->markx2 = wlist->lastx2 = -1;
  219.   wlist->marky1 = wlist->marky2 = wlist->lasty2 = -1;
  220.   wlist->direct = 0;
  221.   return 0;
  222. }
  223.  
  224. /*
  225.  * w_closei removes a window but does not release its storage.  This is used
  226.  * if the window contents must be saved for later use.
  227.  */
  228. void w_closei(wp)
  229. struct wi_str *wp;
  230. {
  231.   int xx, yy, ww, hh;
  232.   int wdes = wp->aes_handle;
  233.  
  234.   wind_get(wdes, WF_CURRXYWH, &xx, &yy, &ww, &hh);
  235.   wind_close(wdes);
  236.   if (!fast)
  237.     graf_shrinkbox(0, 0, 20, 10, xx, yy, ww, hh);
  238.   wind_delete(wdes);
  239. }
  240.  
  241. /*
  242.  * w_close removes a window.
  243.  */
  244. void w_close(wp)
  245. struct wi_str *wp;
  246. {
  247.   /* unlink me */
  248.   wp->prev->next = wp->next;
  249.   wp->next->prev = wp->prev;
  250.   if (wp->next == wp) wlist = NULL;  /* singleton list */
  251.   else if (wlist == wp) wlist = wp->next;
  252.  
  253.   w_closei(wp);
  254.   free(wp->wi_mf.ptr);
  255.   free(wp);
  256. }
  257.  
  258. /* w_resize resizes an existing window.  Also lets you pass in the
  259.  * sliders & titles arguments for the newly-sized window.
  260.  *
  261.  * This used to relocate the window; now it copies the xy.
  262.  * This used to change the font in the window; now it doesn't unless
  263.  * chfont == 1.
  264.  */
  265. int w_resize(wp1, xsiz, ysiz, sliders, titles, chfont)
  266. struct wi_str *wp1;
  267. int xsiz, ysiz;
  268. int sliders, titles;
  269. int chfont;  /* flag: when 0 don't change font */
  270. {
  271.   struct wi_str *wp2;
  272.   static int c[8];
  273.   int tmp_x, tmp_y, tmp_w, tmp_h, wtyp;
  274.   int retcode;
  275.  
  276.   if (wp1->curstate) 
  277.   {
  278.     w_flash(wp1,0);
  279.   }
  280.  
  281.   w_closei(wp1);  /* close it (closes AES window) */
  282.  
  283.             /* what's happening here is that the overlap of screen images between
  284.              * the old & new sizes gets copied into the new window. This is done by
  285.              * deleting the old window, creating a new one of the new size, and
  286.              * copying the appropriate rectangle of screen image over.
  287.              */
  288.  
  289.   /* unlink me */
  290.   wp1->prev->next = wp1->next;
  291.   wp1->next->prev = wp1->prev;
  292.   if (wp1->next == wp1) wlist = NULL;
  293.   else if (wlist == wp1) wlist = wp1->next;
  294.  
  295.   wtyp = (sliders ? WI_WITHSLD : 0) | (titles ? WI_WITHTITLE : 0);
  296.   wind_calc(0,wtyp,wp1->x,wp1->y,wp1->w,wp1->h,
  297.   &tmp_x, &tmp_y, &tmp_w, &tmp_h);
  298.  
  299.   /* open this window with the same workxy as the previous */
  300.   if (w_open(wp1->name, tmp_x, tmp_y, xsiz, ysiz, 
  301.   sliders, titles, (chfont ? curfont : wp1->font))) 
  302.   {
  303.     /* error opening the new copy of the window */
  304.     retcode = -1;
  305.     goto freeold;
  306.   }
  307.  
  308.   wp2 = wlist;
  309.   c[0] = wp1->m_off;
  310.   c[1] = wp1->top_y + max(0, wp1->wi_mf.hpix - wp2->wi_mf.hpix);
  311.   c[2] = c[0] + min(wp1->wi_mf.wpix, wp2->wi_mf.wpix);
  312.   c[3] = c[1] + min(wp1->wi_mf.hpix, wp2->wi_mf.hpix);
  313.   c[4] = wp2->m_off;
  314.   c[5] = wp2->top_y;
  315.   c[6] = c[4] + min(wp1->wi_mf.wpix, wp2->wi_mf.wpix);
  316.   c[7] = c[5] + min(wp1->wi_mf.hpix, wp2->wi_mf.hpix);
  317.  
  318.   /* copy screen */
  319.   vro_cpyfm(screen_handle, FM_COPY, c, (MFDB*)&wp1->wi_mf, (MFDB*)&wp2->wi_mf);
  320.   /* copy parameters */
  321.  
  322.   wp2->fgbg[0] = wp1->fgbg[0];
  323.   wp2->fgbg[1] = wp1->fgbg[1];
  324.   wp2->insmode = wp1->insmode;
  325.  
  326.   wp2->fd = wp1->fd;
  327.   wp2->pid = wp1->pid;
  328.  
  329.   if (wtyp != wp1->wi_mainstyle) 
  330.   {
  331.     /* you're changing the style... copy mainstyle from the original */
  332.     wp2->wi_mainstyle = wp1->wi_mainstyle;
  333.   }
  334.  
  335.           /* if font changed, put cursor at bottom left.  Else put it at old X
  336.            * offset (or right edge if narrower than that), and I can't figure out
  337.            * the calculation for Y.
  338.            */
  339.   if (wp2->font != wp1->font) 
  340.   {
  341.     wp2->cur_x = X0;
  342.     wp2->cur_y = (wp2->y_chrs - 1) * wp2->font->inc_y + Y0;
  343.   }
  344.   else 
  345.   {
  346.     wp2->cur_x = (wp2->x_chrs - 1) * wp2->font->inc_x + X0;
  347.     if (wp1->cur_x < wp2->cur_x)
  348.       wp2->cur_x = wp1->cur_x;
  349.     wp2->cur_y = max(0, wp1->cur_y - c[1]) + Y0;
  350.   }
  351.   
  352.   wp2->state = wp1->state;
  353.   strcpy(wp2->nuname,wp1->nuname);
  354.  
  355.   wp2->discard = wp1->discard; /* was commented out */
  356.   wp2->curskey = wp1->curskey;
  357.   wp2->keypad = wp1->keypad;
  358.   wp2->smooth = wp1->smooth;
  359.   wp2->repeat = wp1->repeat;
  360.   wp2->lfmode = wp1->lfmode;
  361.   
  362.   wp2->nuptr = wp1->nuptr;
  363.   wp2->G0 = wp1->G0;
  364.   wp2->G1 = wp1->G1;
  365.   wp2->chset = wp1->chset;
  366.   
  367.   wp2->app = wp1->app;
  368.   wp2->recv_flag = wp1->recv_flag;
  369.   wp2->ftp_data = wp1->ftp_data;
  370.  
  371.   w_flash(wp2,wp1->curstate);
  372.   retcode = 0;
  373.  
  374. freeold:
  375.   free(wp1->wi_mf.ptr);
  376.   free(wp1);
  377.   return retcode;  /* old window is GONE if this is -1 */
  378. }
  379.  
  380. /* w_rename changes the title bar of a window
  381.  */
  382. void w_rename(wp, name)
  383. struct wi_str *wp;
  384. char *name;
  385. {
  386.   if (name)
  387.     strcpy(wp->name, name);
  388.   if (wp->wi_style & NAME) 
  389.   {
  390.     wind_set(wp->aes_handle, WF_NAME, wp->name, 0, 0);
  391.   }
  392. }
  393. /* w_info changes the info line of a window
  394.  */
  395. void w_info(wp, name)
  396. struct wi_str *wp;
  397. char *name;
  398. {
  399.   if (name)
  400.     strcpy(wp->info, name);
  401.   if (wp->wi_style & NAME) 
  402.   {
  403.     wind_set(wp->aes_handle, WF_INFO, wp->info, 0, 0);
  404.   }
  405. }
  406.  
  407. /* w_redraw redraws part of the screen from window contents.
  408.  * The coordinates are screen relative.
  409.  */
  410. void w_redraw(wp, logic, xx, yy, ww, hh)
  411. struct wi_str *wp;
  412. int logic,xx,yy,ww,hh;
  413. {
  414.   int c[8];
  415.   GRECT t1, t2;
  416.   int wdes = wp->aes_handle;
  417.  
  418.   /* turn vro_cpyfm logic ops into vrt_cpyfm ones */
  419.   if (logic == FM_INVERT) logic = 3;
  420.   else logic = 1;
  421.  
  422.   if (xx+ww > scr_w)
  423.     ww = scr_w - xx;
  424.   if (yy+hh > scr_h+scr_y)
  425.     hh = scr_h+scr_y - yy;
  426.   t2.g_x = xx; 
  427.   t2.g_y = yy;
  428.   t2.g_w = ww; 
  429.   t2.g_h = hh;
  430.   t1.g_x = wp->x; 
  431.   t1.g_y = wp->y;
  432.   t1.g_w = wp->w; 
  433.   t1.g_h = wp->h;
  434.   if (!rc_intersect(&t2, &t1)) 
  435.   {
  436.     return;  /* nothing to do... */
  437.   }
  438.   wind_update(TRUE);
  439.   wind_get(wdes, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  440.   while (t1.g_w && t1.g_h) 
  441.   {
  442.     if (rc_intersect(&t2, &t1)) 
  443.     {
  444.       if (mouse) 
  445.       {
  446.         /* we have to do graphics, so switch the mouse off.
  447.                                      * mouse will be switched on again in main loop.
  448.                                      * this is ugly, but it improves speed a bit...
  449.                                      * (If mouseflicker is ON, we'll turn it on again below)
  450.                                      */
  451.         mouse = 0;
  452.         graf_mouse(M_OFF, NULL);
  453.       }
  454.       c[0] = t1.g_x - wp->x + wp->x_off + wp->m_off;
  455.       c[1] = t1.g_y - wp->y + wp->y_off + wp->top_y - Y0;
  456.       c[2] = c[0] + t1.g_w - 1;
  457.       c[3] = c[1] + t1.g_h - 1;
  458.       c[4] = t1.g_x;
  459.       c[5] = t1.g_y;
  460.       c[6] = c[4] + t1.g_w - 1;
  461.       c[7] = c[5] + t1.g_h - 1;
  462.       vrt_cpyfm(screen_handle, logic, c,
  463.       (MFDB*)&wp->wi_mf, (MFDB*)&screen_mf, wp->fgbg);
  464.     }
  465.     wind_get(wdes, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  466.   }
  467.   wind_update(FALSE);
  468.   /* mouse stays hidden -- we'll make it visible next time it moves */
  469.   /* except if mouseflicker is on, in which case we'll do it NOW */
  470.   if (!mouse && mouseflicker) 
  471.   {
  472.     mouse = 1;
  473.     graf_mouse(M_ON,NULL);
  474.   }
  475. }
  476.  
  477. /* w_update copies a portion of the window to the screen.  Coordinates
  478.  * are window-relative
  479.  */
  480. void w_update(wp, logic, xx, yy, ww, hh)
  481. struct wi_str *wp;
  482. int logic, xx,yy,ww,hh;
  483. {
  484.   w_redraw(wp, logic, xx + wp->x - wp->x_off, 
  485.   yy + wp->y - wp->y_off - wp->top_y + Y0, ww, hh);
  486. }
  487.  
  488. /* w_move sets the window's idea of its own position on the screen
  489.  */
  490.  
  491. void w_move(wp, xx, yy, ww, hh)
  492. struct wi_str *wp;
  493. int xx, yy, ww, hh;
  494. {
  495.   int wdes = wp->aes_handle;
  496.   int flag = 0;
  497.   int m_w, m_h;
  498.   int x1, x2;
  499.   int tmp;
  500.   int c[8];
  501.   int inc_x, inc_y;
  502.  
  503.   wind_calc(1, wp->wi_style, xx, yy, ww, hh, &sdummy, &sdummy, &m_w, &m_h);
  504.   if ((tmp = (m_w-2*X0)%wp->font->inc_x) != 0)
  505.   {
  506.     ww -= tmp;
  507.     m_w -= tmp;
  508.   }
  509.   if ((tmp = (m_h-2*Y0)%wp->font->inc_y) != 0)
  510.   {
  511.     hh -= tmp;
  512.     m_h -= tmp;
  513.   }
  514.   if (m_w>wp->wi_w) ww = ww-(m_w-wp->wi_w);
  515.   if (m_h>wp->wi_h) hh = hh-(m_h-wp->wi_h);
  516.   wind_set(wdes, WF_CURRXYWH, xx, yy, ww, hh);
  517.   wind_get(wdes, WF_WORKXYWH, &wp->x, &wp->y, &wp->w, &wp->h);
  518.   if (wp->x_off+wp->w > wp->wi_w) 
  519.   {
  520.     inc_x = wp->font->inc_x;
  521.     flag = 1;
  522.     wp->x_off = (wp->wi_w - wp->w)/inc_x*inc_x;
  523.   }
  524.   if (wp->y_off+wp->h > wp->wi_h) 
  525.   {
  526.     inc_y = wp->font->inc_y;
  527.     flag = 1;
  528.     wp->y_off = (wp->wi_h - wp->h)/inc_y*inc_y;
  529.   }
  530.   x1 = wp->m_off;
  531.   x2 = (wp->x - wp->x_off) & 15;
  532.   if (x1 != x2) 
  533.   {
  534.     c[0] = x1;
  535.     c[1] = wp->top_y;  /* displayed part of memory form starts here */
  536.     c[2] = x1 + wp->wi_w - 1;
  537.     c[3] = wp->wi_h - 1 + c[1];
  538.     c[4] = x2;
  539.     c[5] = c[1];
  540.     c[6] = x2 + wp->wi_w - 1;
  541.     c[7] = c[3];
  542.     vro_cpyfm(screen_handle, FM_COPY, c, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  543.     wp->m_off = x2;
  544.   }
  545.   if (flag)
  546.     w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  547.   setvslide(wp);
  548.   sethslide(wp);
  549. }
  550.  
  551. /*
  552.  * w_top makes win the top window.
  553.  */
  554.  
  555. void w_top(wp)
  556. struct wi_str *wp;
  557. {
  558.   wind_set(wp->aes_handle, WF_TOP, 0, 0, 0, 0);
  559.  
  560.   if (wlist == wp) return;  /* already top of list */
  561.  
  562.   /* unlink from its current place */
  563.   wp->next->prev = wp->prev;
  564.   wp->prev->next = wp->next;
  565.  
  566.   /* link into top */
  567.   wp->next = wlist;
  568.   wp->prev = wlist->prev;
  569.   wlist->prev->next = wp;
  570.   wlist->prev = wp;
  571.   wlist = wp;
  572. }
  573.  
  574. /*
  575.  * w_bottom finds the bottom window and puts it on top
  576.  */
  577.  
  578. void w_bottom()
  579. {
  580.   struct wi_str *wp;
  581.  
  582.   if (!wlist || wlist->next == wlist) return;
  583.   for (wp = wlist->next; wp->next != wlist; wp = wp->next)  /* do nothing */ ;
  584.   w_top(wp);
  585. }
  586.  
  587. /*
  588.  * w_hide puts the top window on the bottom.
  589.  * (a.k.a. "bury")
  590.  */
  591.  
  592. void w_hide()
  593. {
  594.   struct wi_str *wp, *oldtop;
  595.  
  596.   /* top all the windows, in order, from back to front, except the first. */
  597.   if (!wlist || wlist->next == wlist) return;  /* empty or singleton list */
  598.   oldtop = wlist;  /* window NOT to top */
  599.   for (wp = wlist->prev; wp != oldtop; wp = wp->prev)
  600.     wind_set(wp->aes_handle,WF_TOP, 0,0,0,0);
  601.  
  602.   /* move the top element from wlist to the end of wlist (easy!) */
  603.   wlist = wlist->next;
  604. }
  605.  
  606. #define TINYX 80
  607. #define TINYY 70
  608. /*
  609.  * w_shrink saves current size and location and shrinks to standard tiny size.
  610.  * The second from the top non-shrunk window is placed on top.
  611.  */
  612.  
  613. void w_shrink(wp)
  614. struct wi_str *wp;
  615. {
  616.   int wdes = wp->aes_handle;
  617.   int curx, cury, curw, curh;
  618.   static int slotcount;
  619.  
  620.   /*
  621.            * Don't shrink a window that is currently shrunk
  622.            */
  623.   wind_get(wdes, WF_CURRXYWH, &curx, &cury, &curw, &curh);
  624.   if (curw <= TINYX && cury <= TINYY)
  625.     return;
  626.  
  627.   if (wp->slotno == 0) wp->slotno = ++slotcount;
  628.  
  629.   /*
  630.            * By setting wp->fulled to one and the "previous" size to tiny,
  631.            * we're saying that the current size is the "full" size, and we
  632.            * want to "toggle to" the tiny size.
  633.            */
  634.   wp->fulled = 1;
  635.   wp->px = scr_x + (scr_w - TINYX + 2);
  636.   wp->py = scr_y + ((wp->slotno-1) * (TINYY + 2));
  637.   wp->pw = TINYX;
  638.   wp->ph = TINYY;
  639.  
  640.   /* ensure at least 10 dots of title bar on screen */
  641.   if (wp->py + 10 > scr_y + scr_h) 
  642.   {
  643.     wp->py = wp->py - scr_h + 10;
  644.     wp->px = scr_x + scr_w - TINYY * 2;
  645.   }
  646.   w_full(wp);
  647.  
  648.   /* now top the topmost window which isn't already tiny */
  649.  
  650.   wp = wlist;
  651.   do 
  652.   {
  653.     wdes = wp->aes_handle;
  654.     wind_get(wdes, WF_CURRXYWH, &curx, &cury, &curw, &curh);
  655.     if (curw > TINYX || curh > TINYY) 
  656.     {
  657.       w_full(wp);
  658.       w_top(wp);
  659.       return;
  660.     }
  661.     wp = wp->next;
  662.   } 
  663.   while (wp != wlist);
  664.  
  665.   /* no windows are not shrunk; just leave 'em */
  666. }
  667.  
  668. /* w_full toggles size and location between the current size and
  669.  * the "previous" size.
  670.  */
  671.  
  672. void w_full(wp)
  673. struct wi_str *wp;
  674. {
  675.   int x1, y1, w1, h1;
  676.   int x2, y2, w2, h2;
  677.   int full;
  678.   int wdes = wp->aes_handle;
  679.  
  680.   full = wp->fulled;
  681.  
  682.   /* if already full, set to "previous" size, else to full size */
  683.   if (full) 
  684.   {
  685.     x1 = wp->px;
  686.     y1 = wp->py;
  687.     w1 = wp->pw;
  688.     h1 = wp->ph;
  689.   }
  690.   else
  691.     wind_get(wdes, WF_FULLXYWH, &x1, &y1, &w1, &h1);
  692.  
  693.   wind_get(wdes, WF_CURRXYWH, &x2, &y2, &w2, &h2);
  694.   wp->px = x2;
  695.   wp->py = y2;
  696.   wp->pw = w2;
  697.   wp->ph = h2;
  698.   if (!fast) 
  699.   {
  700.     if (w2>=w1)
  701.       graf_growbox(x1, y1, w1, h1, x2, y2, w2, h2);
  702.     else
  703.       graf_shrinkbox(x1, y1, w1, h1, x2, y2, w2, h2);
  704.   }
  705.  
  706.   x2 = wp->x_off;
  707.   y2 = wp->y_off;
  708.   wp->x_off = wp->px_off;
  709.   wp->y_off = wp->py_off;
  710.   wp->px_off = x2;
  711.   wp->py_off = y2;
  712.  
  713.   w_move(wp, x1, y1, w1, h1);
  714.   w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  715.   wp->fulled = 1;
  716. }
  717.  
  718. void w_arrow(wp, arrow)
  719. struct wi_str *wp;
  720. int arrow;
  721. {
  722.   int inc_x = wp->font->inc_x;
  723.   int inc_y = wp->font->inc_y;
  724.  
  725.   switch (arrow) 
  726.   {
  727.   case 0:  /* page up */
  728.     wp->y_off -= wp->h/inc_y*inc_y;
  729.     goto y_upd;
  730.  
  731.   case 1:  /* page down */
  732.     wp->y_off += wp->h/inc_y*inc_y;
  733.     goto y_upd;
  734.  
  735.   case 2:  /* row up */
  736.     wp->y_off -= inc_y;
  737.     goto y_upd;
  738.  
  739.   case 3:  /* row down */
  740.     wp->y_off += inc_y;
  741.     goto y_upd;
  742.  
  743.   case 4:  /* page left */
  744.     wp->x_off -= wp->w/inc_x*inc_x;
  745.     goto x_upd;
  746.  
  747.   case 5:  /* page right */
  748.     wp->x_off += wp->w/inc_x*inc_x;
  749.     goto x_upd;
  750.  
  751.   case 6:  /* column left */
  752.     wp->x_off -= inc_x;
  753.     goto x_upd;
  754.  
  755.   case 7:  /* column right */
  756.     wp->x_off += inc_x;
  757.     goto x_upd;
  758.   }
  759.  
  760. x_upd:
  761.   if (wp->x_off<0) wp->x_off = 0; 
  762.   else
  763.     if (wp->x_off+wp->w > wp->wi_w) wp->x_off = (wp->wi_w - wp->w)/inc_x*inc_x;
  764.   sethslide(wp);
  765.   goto upd;
  766.  
  767. y_upd:
  768.   if (wp->y_off<0) wp->y_off = 0; 
  769.   else
  770.     if (wp->y_off+wp->h > wp->wi_h) wp->y_off = (wp->wi_h - wp->h)/inc_y*inc_y;
  771.   setvslide(wp);
  772.  
  773. upd:
  774.   w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  775. }
  776.  
  777. void w_slide(wp, hor, val)
  778. struct wi_str *wp;
  779. int hor, val;
  780. {
  781.   int tmp;
  782.  
  783.   if (hor) 
  784.   {
  785.     tmp = wp->font->inc_x;
  786.     wp->x_off = (int)(((long)val*(wp->wi_w-wp->w)/1000)/tmp*tmp);
  787.     sethslide(wp);
  788.   }
  789.   else 
  790.   {
  791.     tmp = wp->font->inc_y;
  792.     wp->y_off = (int)(((long)val*(wp->wi_h-wp->h)/1000)/tmp*tmp);
  793.     setvslide(wp);
  794.   }
  795.   w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  796. }
  797.  
  798. void sethslide(wp)
  799. struct wi_str *wp;
  800. {
  801.   int tmp;
  802.   int wdes = wp->aes_handle;
  803.  
  804.   if (wp->wi_style & HSLIDE) 
  805.   {
  806.     if (wp->wi_w == wp->w) tmp = 0;
  807.     else tmp = (int)((long)1000*wp->x_off/(wp->wi_w-wp->w));
  808.     if (tmp != wp->hspos) 
  809.     {
  810.       wind_set(wdes, WF_HSLIDE, tmp, 0, 0, 0);
  811.       wp->hspos = tmp;
  812.     }
  813.  
  814.     tmp = (int)((long)1000*wp->w/wp->wi_w);
  815.     if (tmp != wp->hssiz) 
  816.     {
  817.       wind_set(wdes, WF_HSLSIZE, tmp, 0, 0, 0);
  818.       wp->hssiz = tmp;
  819.     }
  820.   }
  821. }
  822.  
  823. void setvslide(wp)
  824. struct wi_str *wp;
  825. {
  826.   int tmp;
  827.   int wdes = wp->aes_handle;
  828.  
  829.   if (wp->wi_style & VSLIDE) 
  830.   {
  831.     if (wp->wi_h == wp->h) tmp = 0;
  832.     else tmp = (int)((long)1000*wp->y_off/(wp->wi_h-wp->h));
  833.     if (tmp != wp->vspos) 
  834.     {
  835.       wind_set(wdes, WF_VSLIDE, tmp, 0, 0, 0);
  836.       wp->vspos = tmp;
  837.     }
  838.  
  839.     tmp = (int)((long)1000 * wp->h / wp->wi_h);
  840.     if (tmp != wp->vssiz) 
  841.     {
  842.       wind_set(wdes, WF_VSLSIZE, tmp, 0, 0, 0);
  843.       wp->vssiz = tmp;
  844.     }
  845.   }
  846. }
  847.  
  848. /*
  849.  * flash the cursor in a window; if it's not the last one we flashed,
  850.  * un_flash that one
  851.  */
  852. void w_flash(wp, state)
  853. struct wi_str *wp;
  854. int state;
  855. {
  856.   static struct wi_str *wp_last = NULL;
  857.   int t[8];
  858.  
  859. /*  if (wp_last && wp != wp_last) w_flash(wp_last, 1);*/
  860.   wp_last = wp;
  861.   if (wp->curstate == state) return;
  862.   if (state == 2)
  863.     wp->curstate = !wp->curstate;
  864.   else
  865.     wp->curstate = state;
  866.   t[0] = t[4] = wp->cur_x + wp->m_off;
  867.   t[1] = t[5] = wp->cur_y;
  868.   t[2] = t[6] = t[0]+wp->font->inc_x-1;
  869.   t[3] = t[7] = t[1]+wp->font->inc_y-1;
  870.   vro_cpyfm(screen_handle, FM_INVERT, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  871.   w_update(wp, FM_COPY, wp->cur_x, wp->cur_y, wp->font->inc_x, wp->font->inc_y);
  872. }
  873.  
  874. /* w_output prints a string onto the window.  The string may
  875.  * contain control chars and escape sequences.  Its length is given,
  876.  * so you can even output NULs.
  877.  */
  878. void w_output(wp, ptr, charcount)
  879. struct wi_str *wp;
  880. unsigned char *ptr;
  881. short charcount;
  882. {
  883.   unsigned char ch;
  884.   int inc_x, cur_x;
  885.   int inc_y, cur_y;
  886.   int t[8];
  887.   int f_x, f_y, f_mod;
  888.   int scrolled;  /* Number of scrolling operations delayed */
  889.   int xsiz, ysiz;/* Size in chars of terminal emulation for this window*/
  890.   register unsigned char *sptr;
  891.   register unsigned long *dptr;
  892.   register unsigned long mask;
  893.   register int shift;
  894.   register unsigned long valu;
  895.   int count = 0;
  896.   char * fdata;
  897.   long width;
  898.   char * wimfptr;
  899.   int moffincx;
  900.   int state;
  901.  
  902.   if (!wp->font) return;
  903.   state = wp->state;
  904.   inc_x = wp->font->inc_x;
  905.   inc_y = wp->font->inc_y;
  906.   xsiz = wp->x_chrs;
  907.   ysiz = wp->y_chrs;
  908.   f_x = cur_x = wp->cur_x;
  909.   f_y = cur_y = wp->cur_y;
  910.  
  911.   /*
  912.            * This sets "hard update" any time the bottom N lines of the buffer are
  913.            * being used -- that is, the overflow below the visible screen. This is
  914.            * seven lines in 8 when you're doing glass-tty scrolling things.  This
  915.            * is wrong & slow.
  916.            */
  917.  
  918.   scrolled = wp->top_y/inc_y;
  919.  
  920.   fdata = wp->font->f_data;
  921.   width = 2 * wp->wi_mf.wwords;
  922.   wimfptr = ((char *) (wp-> wi_mf.ptr)) - 2;
  923.   moffincx = wp->m_off + inc_x - 1;
  924.   f_mod = 0;
  925.  
  926.   if (wp->curstate) 
  927.   {
  928.     w_flash(wp, 0);
  929.   }
  930.  
  931.   while (charcount--) 
  932.   {
  933.     ch = *ptr++;
  934.     if(ch == CAN)
  935.     {
  936.      state = S_NORMAL;
  937.      continue;
  938.     }
  939.       if(ch < ' ') 
  940.       {  /* not printable character */
  941.                                     /*
  942.                                      * If you've modified the screen in this incarnation and you aren't
  943.                                      * "scrolled", update before any non-printing character.  This
  944.                                      * appears to call w_update for the line you're on, from the X you
  945.                                      * started from to the X you're at now.  I think this is
  946.                                      * inefficient, but I'm not sure yet.  If you're in insert mode,
  947.                                      * update the whole line from the starting X to the end of the
  948.                                      * line.
  949.                                      *
  950.                                      * I changed this to set "scrolled" if you get here and f_mod is
  951.                                      * TRUE.  That means simple updates on one line (no non-printing
  952.                                      * chars) don't happen in "scrolled" mode, but anything more
  953.                                      * complicated does.  This is also conditional on jerky_updates,
  954.                                      * which is the visual result.
  955.                                      */
  956.  
  957.         if (f_mod)
  958.         {
  959.          if(!jerky_updates) scrolled++;
  960.         }
  961.         switch (ch) 
  962.         {
  963.         case '\007':  /* Bell */
  964.           if (audibell) (void)Bconout(2, '\007');
  965.           if (visibell) 
  966.           {
  967.             w_redraw(wp, FM_INVERT, wp->x, wp->y, wp->w, wp->h);
  968.             w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  969.             /* Should clear flag to prevent need for next update? */
  970.           }
  971.           break;
  972.  
  973.         case '\r':  /* Carriage Return */
  974.           cur_x = X0;
  975.           break;
  976.  
  977.         case '\b':  /* Backspace */
  978.           if (cur_x>X0) cur_x -= inc_x;
  979.           break;
  980.  
  981.         case '\n':  /* Newline */
  982.           if (cur_y + inc_y >= inc_y * (wp->bottomline + 1) + wp->top_y)
  983.           {
  984.             scrollup(wp, wp->topline, wp->bottomline - wp->topline, 1);
  985.           if (! scrolled)
  986.             w_update(wp, FM_COPY, X0, wp->topline * inc_y, xsiz * inc_x,
  987.             wp->top_y + (inc_y * (wp->bottomline - wp->topline + 1)));
  988.           }
  989.           else cur_y += inc_y;
  990.           if(wp->lfmode) cur_x = X0;
  991.           break;
  992.  
  993.         case '\t':  /* Tab */
  994.           cur_x = (((cur_x - X0)/inc_x/8 + 1))*inc_x*8+X0;
  995.           break;
  996.  
  997.         case ENQ:  /* ENQ - get answer back */
  998.           sprintf(o_str,"TUW VT100");
  999.           o_len = (int)strlen(o_str);
  1000.           tcp_out(wp->pid,o_str,o_len);
  1001.           break;
  1002.         case SI:
  1003.           wp->chset = 0;
  1004.           break;
  1005.         case SO:
  1006.           wp->chset = 1;
  1007.           break;
  1008.         case '\033':  /* ESC */
  1009.           state = S_ESC;
  1010.           count = 0;  /* count is used for insert or delete line */
  1011.           break;
  1012.         }
  1013.         f_x = cur_x;
  1014.         f_y = cur_y;
  1015.       }
  1016.     else
  1017.     {
  1018.     switch (state) 
  1019.     {
  1020.     case S_NORMAL:
  1021.       if (ch >= ' ') 
  1022.       {
  1023.         if (wp->insmode) 
  1024.         {  /* open space for character */
  1025.           t[0] = cur_x + wp->m_off;
  1026.           t[1] = t[5] = cur_y;
  1027.           t[2] = (xsiz - 1) * inc_x + wp->m_off - 1;
  1028.           t[3] = t[7] = cur_y + inc_y - 1;
  1029.           t[4] = t[0] + inc_x;
  1030.           t[6] = t[2] + inc_x;
  1031.           vro_cpyfm(screen_handle, FM_COPY, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1032.         }
  1033.  
  1034.         /* paint the character (only if it's in range for this font) */
  1035.         if (ch < wp->font->nchars) 
  1036.         {
  1037.           ch &= 0x7f;
  1038.           if(wp->chset == 0)
  1039.           {
  1040.             if(wp->G0 == '0' && ch >= '_') ch -= '_';
  1041.           }
  1042.           else
  1043.             if(wp->G1 == '0' && ch >= '_') ch -= '_';
  1044.           sptr = (unsigned char *)(fdata+ch*16);
  1045.           dptr = (unsigned long *)(wimfptr + cur_y*width
  1046.               + (((moffincx + cur_x)>>4)<<1));
  1047.           shift = 15 - ((moffincx + cur_x)&15);
  1048.  
  1049.           /* to get overstrike, set mask to -1 */
  1050.           mask = (-1L << (shift+inc_x)) | ((1 << shift)-1);
  1051.           if (wp->inverse) 
  1052.           {
  1053.             for (count = inc_y; count; count--) 
  1054.             {
  1055.               valu = (((long)(*sptr++)) << shift) ^ ~mask;
  1056.               *dptr = (*dptr&mask)|valu;
  1057.               ((char *)dptr) += width;
  1058.             }
  1059.           }
  1060.           else 
  1061.           {
  1062.             for (count = inc_y; count; count--) 
  1063.             {
  1064.               valu = ((long)(*sptr++))<<shift;
  1065.               *dptr = (*dptr&mask)|valu;
  1066.               ((char *)dptr) += width;
  1067.             }
  1068.           }
  1069.         }
  1070.         cur_x += inc_x;
  1071.         f_mod = 1;
  1072.         if (cur_x > inc_x * xsiz) 
  1073.         {  /* autowrap */
  1074.           if (wp->discard) 
  1075.           {
  1076.             cur_x -= inc_x;  /* back to last char position */
  1077.           }
  1078.           else 
  1079.           {
  1080.             cur_y += inc_y;
  1081.             if (cur_y >= wp->top_y + inc_y * ysiz) 
  1082.             {
  1083.               wp->top_y += inc_y;
  1084.               ++ scrolled;
  1085.             }
  1086.             if (! scrolled) 
  1087.             {
  1088.               w_update(wp, FM_COPY, f_x, f_y, cur_x-f_x, inc_y);
  1089.               f_mod = 0;
  1090.             }
  1091.             cur_x = X0;
  1092.  
  1093.             f_x = cur_x;
  1094.             f_y = cur_y;
  1095.           }
  1096.         }
  1097.       } 
  1098.       break;
  1099.  
  1100.     case S_CHS0:
  1101.       wp->G0 = ch;
  1102.       state = S_NORMAL;
  1103.       break;
  1104.       
  1105.     case S_CHS1:
  1106.       wp->G1 = ch;
  1107.       state = S_NORMAL;
  1108.       break;
  1109.  
  1110.     case S_ESC:
  1111.       switch (ch) 
  1112.       {
  1113.       case '[':  /* CSI */
  1114.         state = S_CSI;
  1115.         wp->val1 = wp->val2 = wp->valcnt = 0;
  1116.         break;
  1117.       case '(':
  1118.         state = S_CHS0;
  1119.         break;
  1120.       case ')':
  1121.         state = S_CHS1;
  1122.         break;
  1123.       case '7':  /* AKP: save cursor location */
  1124.         wp->save_x = cur_x;
  1125.         wp->save_y = cur_y;
  1126.         state = S_NORMAL;
  1127.         break;
  1128.       case '8':  /* AKP: restore saved location */
  1129.         f_x = cur_x = wp->save_x;
  1130.         f_x = cur_y = wp->save_y;
  1131.         state = S_NORMAL;
  1132.         break;
  1133.       case '>':  /* reset keypad (numeric) mode */
  1134.         wp->keypad = 0;
  1135.         state = S_NORMAL;
  1136.         break;
  1137.       case '=':  /* set keypad (application) mode */
  1138.         wp->keypad = 1;
  1139.         state = S_NORMAL;
  1140.         break;
  1141.       case 'Z':  /* terminal ID */
  1142.         /* this is obsolete. use ESC [ c */
  1143.         state = S_NORMAL;
  1144.         break;
  1145.       case 'c':  /* reset to initial state */
  1146.         vt100_reset(wp);
  1147.         wp->discard = 1;
  1148.         state = S_NORMAL;
  1149.         break;
  1150.       case 'H':  /* set tab at current position */
  1151.         state = S_NORMAL;
  1152.         break;
  1153.       case 'E':  /* next line */
  1154.           cur_x = X0;
  1155.       case 'D':  /* index */
  1156.         cur_y += inc_y;
  1157.         if (cur_y >= inc_y * (wp->bottomline+1) + wp->top_y)
  1158.         {
  1159.           wp->top_y += inc_y;
  1160.           ++ scrolled;
  1161.         }
  1162.         state = S_NORMAL;
  1163.         break;
  1164.       case 'M':  /* Reverse Index (does possible reverse scroll) */
  1165.         if (cur_y != wp->top_y + (wp->topline * inc_y)) 
  1166.         {
  1167.           cur_y -= inc_y;
  1168.         }
  1169.         else
  1170.         {
  1171.           scrolldn(wp, cur_y/inc_y, wp->bottomline - wp->topline, 1);
  1172.           if (! scrolled)
  1173.             w_update(wp, FM_COPY, X0, cur_y, xsiz * inc_x,
  1174.             wp->top_y + (inc_y * (wp->bottomline - wp->topline + 1)));
  1175.         }
  1176.         state = S_NORMAL;
  1177.         break;
  1178.       case '#':
  1179.         state = S_ALIGN;
  1180.         break;
  1181.       default:  /* Unknown escape sequence */
  1182.         state = S_NORMAL;
  1183.         break;
  1184.       }
  1185.       break;
  1186.     case S_ALIGN:
  1187.       if(ch == '8')
  1188.       {
  1189.           cur_x = X0;
  1190.           cur_y = wp->top_y = Y0;
  1191.        do
  1192.        {
  1193.           sptr = (unsigned char *)(fdata+'E'*16);
  1194.           dptr = (unsigned long *)(wimfptr + cur_y*width
  1195.               + (((moffincx + cur_x)>>4)<<1));
  1196.           shift = 15 - ((moffincx + cur_x)&15);
  1197.  
  1198.           /* to get overstrike, set mask to -1 */
  1199.           mask = (-1L << (shift+inc_x)) | ((1 << shift)-1);
  1200.  
  1201.           for (count = inc_y; count; count--) 
  1202.           {
  1203.             valu = ((long)(*sptr++))<<shift;
  1204.             *dptr = (*dptr&mask)|valu;
  1205.             ((char *)dptr) += width;
  1206.           }
  1207.         cur_x += inc_x;
  1208.         f_mod = 1;
  1209.         if (cur_x > inc_x * xsiz) 
  1210.         { 
  1211.             cur_y += inc_y;
  1212.             cur_x = X0;
  1213.         }
  1214.        }
  1215.        while(cur_y < (Y0 + inc_y * ysiz));
  1216.  
  1217.        f_mod = 0;
  1218.        cur_x = f_x = X0;
  1219.        cur_y = f_y = Y0;
  1220.        w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  1221.       }
  1222.       state = S_NORMAL;
  1223.       break;
  1224.     case S_CSI:
  1225.       wp->valcnt = 0;
  1226.       switch (ch) 
  1227.       {
  1228.       case '?':
  1229.         state = S_QUE;
  1230.         wp->val1 = 0;
  1231.         break;
  1232.       case '0':
  1233.       case '1':
  1234.       case '2':
  1235.       case '3':
  1236.       case '4':
  1237.       case '5':
  1238.       case '6':
  1239.       case '7':
  1240.       case '8':
  1241.       case '9':
  1242.         state = S_NUM1;
  1243.         wp->valcnt = 0;
  1244.         wp->val[0] = wp->val1 = ch - '0';
  1245.         break; 
  1246.       case 'm':  /* Exit Inverse */
  1247.         wp->inverse = 0;
  1248.         state = S_NORMAL;
  1249.         break;
  1250.       default:  /* other escape sequence, continue as if parameter 0 */
  1251.         state = S_NUM1;
  1252.         wp->valcnt = 0;
  1253.         wp->val[0] = 0;
  1254.         ptr--;
  1255.         charcount++;
  1256.         break;
  1257.       }
  1258.       break;
  1259.     case S_NUM1:
  1260.       switch (ch) 
  1261.       {
  1262.       case '0':
  1263.       case '1':
  1264.       case '2':
  1265.       case '3':
  1266.       case '4':
  1267.       case '5':
  1268.       case '6':
  1269.       case '7':
  1270.       case '8':
  1271.       case '9':
  1272.         wp->val1 = wp->val[0] = (wp->val1*10) + ch - '0';
  1273.         break; 
  1274.       case ';':
  1275.         state = S_NUM2;
  1276.         wp->valcnt = 1;
  1277.         wp->val[1] = 0;
  1278.         break;
  1279.       case 'J':
  1280.         switch(wp->val1)
  1281.         {
  1282.         case 0:  /* Clear to End of Screen */
  1283.           lineerase(wp, cur_y / inc_y + 1, ysiz - 1 + wp->top_y / inc_y);
  1284.           if (! scrolled)
  1285.             w_update(wp, FM_COPY, X0, cur_y + inc_y, xsiz*inc_x, ysiz*inc_y);
  1286.           t[0] = t[4] = cur_x + wp->m_off;
  1287.           t[1] = t[5] = cur_y;
  1288.           t[2] = t[6] = X0-1 + xsiz*inc_x +wp->m_off;
  1289.           t[3] = t[7] = cur_y+inc_y-1;
  1290.           vro_cpyfm(screen_handle, FM_CLEAR, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1291.           if (! scrolled)
  1292.             w_update(wp, FM_COPY, cur_x, cur_y, xsiz * inc_x - cur_x, inc_y);
  1293.           state = S_NORMAL;
  1294.           break;
  1295.         case 1:  /* Clear from beginning of screen */
  1296.           if(cur_y >= inc_y) lineerase(wp, 0, cur_y/inc_y - 1);  /* clear top to this line */
  1297.           ++scrolled;
  1298.           t[0] = t[4] = wp->m_off;  /* init X */
  1299.           t[1] = t[5] = cur_y;  /* init Y */
  1300.           t[2] = t[6] = cur_x + wp->m_off + inc_x - 1;  /* final X */
  1301.           t[3] = t[7] = cur_y+inc_y-1;
  1302.           vro_cpyfm(screen_handle, FM_CLEAR, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1303.           ++scrolled;
  1304.           state = S_NORMAL;
  1305.           break;
  1306.         case 2:  /* Clear whole Screen */
  1307.           f_x = cur_x = X0;
  1308.           wp->top_y = f_y = cur_y = Y0;
  1309.           wp->inverse = 0;
  1310.           wp->insmode = 0;
  1311.           lineerase(wp, 0, ysiz - 1 + MAXSCROLLED);
  1312.           ++ scrolled;
  1313.           state = S_NORMAL;
  1314.           break;
  1315.         }
  1316.         break;
  1317.       case 'K':
  1318.         switch(wp->val1)
  1319.         {
  1320.         case 0:  /* Clear to End of Line */
  1321.           t[0] = t[4] = cur_x + wp->m_off;
  1322.           t[1] = t[5] = cur_y;
  1323.           t[2] = t[6] = X0-1 + xsiz*inc_x +wp->m_off;
  1324.           t[3] = t[7] = cur_y+inc_y-1;
  1325.           vro_cpyfm(screen_handle, FM_CLEAR, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1326.           if (! scrolled)
  1327.             w_update(wp, FM_COPY, cur_x, cur_y, xsiz * inc_x - cur_x, inc_y);
  1328.           state = S_NORMAL;
  1329.           break;
  1330.         case 1:  /* Clear from beginning of line */
  1331.           t[0] = t[4] = wp->m_off;  /* init X */
  1332.           t[1] = t[5] = cur_y;  /* init Y */
  1333.           t[2] = t[6] = cur_x + wp->m_off + inc_x -1;  /* final X */
  1334.           t[3] = t[7] = cur_y+inc_y-1;
  1335.           vro_cpyfm(screen_handle, FM_CLEAR, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1336.           ++scrolled;
  1337.           state = S_NORMAL;
  1338.           break;
  1339.         case 2:  /* erase entire line, cursor to left */
  1340.           t[0] = t[4] = wp->m_off;
  1341.           t[1] = t[5] = cur_y;
  1342.           t[2] = t[6] = X0-1 + xsiz*inc_x + wp->m_off;
  1343.           t[3] = t[7] = cur_y+inc_y-1;
  1344.           vro_cpyfm(screen_handle, FM_CLEAR, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1345.           ++scrolled;
  1346.           cur_x = X0;
  1347.           state = S_NORMAL;
  1348.           break;
  1349.         }
  1350.         break;  
  1351.       case 'H':  /* special case cursor set */
  1352.       case 'f':
  1353.         if(wp->val1 != 0) wp->val1--;
  1354.         if(wp->origmode) wp->val1 += wp->topline;
  1355.         f_x = cur_x = X0;
  1356.         f_y = cur_y = wp->val1*inc_y + wp->top_y;
  1357.         state = S_NORMAL;
  1358.         break;
  1359.       case 'A':  /* Cursor Up */
  1360.         if(wp->val1 == 0) wp->val1 = 1;
  1361.         for(;wp->val1;wp->val1--)
  1362.         if(wp->origmode)
  1363.         {
  1364.           if (cur_y > wp->topline*inc_y + wp->top_y) 
  1365.           {
  1366.             cur_y -= inc_y;
  1367.           }
  1368.         }
  1369.         else
  1370.         {
  1371.           if (cur_y!=wp->top_y) 
  1372.           {
  1373.             cur_y -= inc_y;
  1374.           }
  1375.         }
  1376.         state = S_NORMAL;
  1377.         break;
  1378.       case 'B':  /* Cursor Down */
  1379.         if(wp->val1 == 0) wp->val1 = 1;
  1380.         for(;wp->val1;wp->val1--)
  1381.         if(wp->origmode)
  1382.         {
  1383.           if ((cur_y + inc_y) < (wp->bottomline + 1)*inc_y) 
  1384.           {
  1385.             cur_y += inc_y;
  1386.           }
  1387.         }
  1388.         else
  1389.         {
  1390.           if ((cur_y + inc_y) < (wp->top_y + (inc_y * ysiz))) 
  1391.           {
  1392.             cur_y += inc_y;
  1393.           }
  1394.         }
  1395.         state = S_NORMAL;
  1396.         break;
  1397.       case 'C':  /* Cursor Right */
  1398.         if(wp->val1 == 0) wp->val1 = 1;
  1399.         for(;wp->val1;wp->val1--)
  1400.           if (cur_x < (xsiz - 1) * inc_x) cur_x += inc_x;
  1401.         state = S_NORMAL;
  1402.         break;
  1403.       case 'D':  /* Cursor Left */
  1404.         if(wp->val1 == 0) wp->val1 = 1;
  1405.         for(;wp->val1;wp->val1--)
  1406.           if (cur_x > X0) cur_x -= inc_x;
  1407.         state = S_NORMAL;
  1408.         break;
  1409.       case 'L':  /* Insert Line */
  1410.         if(wp->val1 == 0) wp->val1 = 1;
  1411.         wp->val1 = min(wp->val1, cur_y/inc_y - wp->topline);
  1412.         scrolldn(wp, cur_y/inc_y, (wp->bottomline + 1) - (cur_y - wp->top_y + Y0)/inc_y - wp->val1, wp->val1);
  1413.         if (! scrolled)
  1414.           w_update(wp, FM_COPY, X0, cur_y, xsiz * inc_x,
  1415.           (wp->bottomline + 1) * inc_y - cur_y + wp->top_y - Y0);
  1416.         state = S_NORMAL;
  1417.         break;
  1418.       case 'M':  /* Delete Line */
  1419.         if(wp->val1 == 0) wp->val1 = 1;
  1420.         wp->val1 = min(wp->val1, wp->bottomline - cur_y/inc_y);
  1421.         scrollup(wp, cur_y / inc_y,
  1422.         wp->bottomline - (cur_y - wp->top_y + Y0)/inc_y - wp->val1 + 1, wp->val1);
  1423.         if (! scrolled)
  1424.           w_update(wp, FM_COPY, X0, cur_y, xsiz * inc_x,
  1425.           (wp->bottomline + 1) * inc_y - cur_y + wp->top_y - Y0);
  1426.         state = S_NORMAL;
  1427.         break;
  1428.       case 'P':  /* Delete Character */
  1429.         if(wp->val1 == 0) wp->val1 = 1;
  1430.         for(;wp->val1;wp->val1--)
  1431.         {
  1432.           t[0] = cur_x + inc_x + wp->m_off;
  1433.           t[1] = t[5] = cur_y;
  1434.           t[2] = X0 - 1 + xsiz * inc_x + wp->m_off;
  1435.           t[3] = t[7] = cur_y+inc_y - 1;
  1436.           t[4] = t[0] - inc_x;
  1437.           t[6] = t[2] - inc_x;
  1438.           vro_cpyfm(screen_handle, FM_COPY, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1439.           t[0] = t[4] = X0 + (xsiz - 1) * inc_x + wp->m_off;
  1440.           t[2] = t[6] = t[0] + inc_x - 1;
  1441.           vro_cpyfm(screen_handle, FM_CLEAR, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  1442.         }
  1443.         if (! scrolled)
  1444.           w_update(wp, FM_COPY, cur_x, cur_y, xsiz * inc_x - (cur_x - X0),
  1445.           inc_y);
  1446.         state = S_NORMAL;
  1447.         break;
  1448.       case 'h':  /* Insert Mode */
  1449.         switch(wp->val1)
  1450.         {
  1451.         case 4:
  1452.           wp->insmode = 1;
  1453.           break;
  1454.         case 20:
  1455.           wp->lfmode = 1;
  1456.           state = S_NORMAL;
  1457.           break;
  1458.         }
  1459.         state = S_NORMAL;
  1460.         break;
  1461.       case 'l':  /* End Insert */
  1462.         switch(wp->val1)
  1463.         {
  1464.         case 4:
  1465.           wp->insmode = 0;
  1466.           break;
  1467.         case 20:
  1468.           wp->lfmode = 0;
  1469.           state = S_NORMAL;
  1470.           break;
  1471.         }
  1472.         state = S_NORMAL;
  1473.         break;
  1474.       case 'm':
  1475.         switch(wp->val1)
  1476.         {
  1477.         case 0:  /* Exit Inverse */
  1478.           wp->inverse = 0;
  1479.           break;
  1480.         default:
  1481.           wp->inverse = 1;
  1482.         }
  1483.         state = S_NORMAL;
  1484.         break;
  1485.       case 'n':
  1486.        switch(wp->val1)
  1487.        {
  1488.          case 5:
  1489.            sprintf(o_str,"\033[0n");
  1490.            o_len = (int)strlen(o_str);
  1491.            tcp_out(wp->pid,o_str,o_len);
  1492.          break;
  1493.          case 6:
  1494.            wp->val1 = 1 + (cur_y - wp->top_y)/inc_y;
  1495.            wp->val2 = 1 + (cur_x - X0)/inc_x;
  1496.            sprintf(o_str,"\033[%d;%dR",wp->val1,wp->val2);
  1497.            o_len = (int)strlen(o_str);
  1498.            tcp_out(wp->pid,o_str,o_len);
  1499.          break;
  1500.        }
  1501.        break; 
  1502.       case 'c':
  1503.        sprintf(o_str,"\033[?1;2c");
  1504.        o_len = (int)strlen(o_str);
  1505.        tcp_out(wp->pid,o_str,o_len);
  1506.        break;
  1507.       default:
  1508.         state = S_NORMAL;
  1509.         break;
  1510.       }
  1511.       break;
  1512.     case S_QUE:
  1513.       switch(ch)
  1514.       {
  1515.       case '0':
  1516.       case '1':
  1517.       case '2':
  1518.       case '3':
  1519.       case '4':
  1520.       case '5':
  1521.       case '6':
  1522.       case '7':
  1523.       case '8':
  1524.       case '9':
  1525.         wp->val1 = (wp->val1*10) + ch - '0';
  1526.         break; 
  1527.       case 'l':
  1528.         switch(wp->val1)
  1529.         {
  1530.         case 1:
  1531.           wp->curskey = 0;
  1532.           state = S_NORMAL;
  1533.           break;
  1534.         case 3:
  1535.           if (w_resize(wp, 80, 24, wp->sliders, wp->titles, 0));
  1536.           xsiz = 80;
  1537.           wp = wlist;
  1538.           wp->colwidth = 0;
  1539.           f_x = cur_x = X0;
  1540.           f_y = cur_y = Y0;
  1541.           width = 2 * wp->wi_mf.wwords;
  1542.           wimfptr = ((char *) (wp-> wi_mf.ptr)) - 2;
  1543.           moffincx = wp->m_off + inc_x - 1;
  1544.           lineerase(wp, 0, ysiz - 1 + MAXSCROLLED);
  1545.           ++ scrolled;
  1546.           state = S_NORMAL;
  1547.           break;
  1548.         case 4:
  1549.           wp->smooth = 0;
  1550.           state = S_NORMAL;
  1551.           break;
  1552.         case 5:
  1553.           wp->fgbg[0] = (ncolors-1);
  1554.           wp->fgbg[1] = 0;
  1555.           state = S_NORMAL;
  1556.           scrolled++;  /* force a hard update */
  1557.           break;
  1558.         case 6:
  1559.           wp->origmode = 0;
  1560.           f_y = cur_y = wp->val1*inc_y + wp->top_y;
  1561.           f_x = cur_x = X0;
  1562.           state = S_NORMAL;
  1563.           break;
  1564.         case 7:
  1565.           wp->discard = 1;
  1566.           state = S_NORMAL;
  1567.           break;
  1568.         case 8:
  1569.           wp->repeat = 0;
  1570.           state = S_NORMAL;
  1571.           break;
  1572.         }
  1573.         break;
  1574.       case 'h':
  1575.         switch(wp->val1)
  1576.         {
  1577.         case 1:
  1578.           wp->curskey = 1;
  1579.           state = S_NORMAL;
  1580.           break;
  1581.         case 3:
  1582.           if (w_resize(wp, 132, 24, wp->sliders, wp->titles, 0));
  1583.           xsiz = 132;
  1584.           wp = wlist;
  1585.           wp->colwidth = 1;
  1586.           f_x = cur_x = X0;
  1587.           f_y = cur_y = Y0;
  1588.           width = 2 * wp->wi_mf.wwords;
  1589.           wimfptr = ((char *) (wp-> wi_mf.ptr)) - 2;
  1590.           moffincx = wp->m_off + inc_x - 1;
  1591.           lineerase(wp, 0, ysiz - 1 + MAXSCROLLED);
  1592.           ++ scrolled;
  1593.           state = S_NORMAL;
  1594.           break;
  1595.         case 4:
  1596.           wp->smooth = 1;
  1597.           state = S_NORMAL;
  1598.           break;
  1599.         case 5:
  1600.           wp->fgbg[0] = 0;
  1601.           wp->fgbg[1] = (ncolors-1);
  1602.           state = S_NORMAL;
  1603.           scrolled++;  /* force a hard update */
  1604.           break;
  1605.         case 6:
  1606.           wp->origmode = 1;
  1607.           state = S_NORMAL;
  1608.           f_y = cur_y = wp->val1*inc_y + wp->top_y;
  1609.           f_x = cur_x = X0;
  1610.           break;
  1611.         case 7:
  1612.           wp->discard = 0;
  1613.           state = S_NORMAL;
  1614.           break;
  1615.         case 8:
  1616.           wp->repeat = 1;
  1617.           state = S_NORMAL;
  1618.           break;
  1619.         }
  1620.       }
  1621.       break;
  1622.     case S_NUM2:
  1623.       switch (ch) 
  1624.       {
  1625.       case '0':
  1626.       case '1':
  1627.       case '2':
  1628.       case '3':
  1629.       case '4':
  1630.       case '5':
  1631.       case '6':
  1632.       case '7':
  1633.       case '8':
  1634.       case '9':
  1635.         wp->val2 = wp->val[wp->valcnt] = (wp->val[wp->valcnt]*10) + ch - '0';
  1636.         break; 
  1637.       case ';':
  1638.         if(wp->valcnt < 8) wp->valcnt++;
  1639.         wp->val[wp->valcnt] = 0;
  1640.         break;
  1641.       case 'H':
  1642.       case 'f':
  1643.         if(wp->val1 != 0) wp->val1--;
  1644.         if(wp->val2 != 0) wp->val2--;
  1645.         if(wp->origmode) wp->val1 += wp->topline;
  1646.         if (wp->val1 > ysiz-1) wp->val1 = ysiz-1;
  1647.         if(wp->origmode && wp->val1 > wp->bottomline) wp->val1 = wp->bottomline;
  1648.         f_y = cur_y = wp->val1*inc_y + wp->top_y;
  1649.         if (wp->val2 > xsiz-1) wp->val2 = xsiz-1;
  1650.         f_x = cur_x = wp->val2*inc_x +X0;
  1651.         state = S_NORMAL;
  1652.         break;
  1653.       case 'r':
  1654.         /* change scrolling region */
  1655.         if(wp->val1 == 0 && wp->val2 == 0) /* empty resets to whole screen */
  1656.         {
  1657.          wp->val1 = 1;
  1658.          wp->val2 = 24;
  1659.         }
  1660.         if(wp->val1 != 0) wp->val1--;
  1661.         if(wp->val2 != 0) wp->val2--;
  1662.         wp->topline = wp->val1;
  1663.         wp->bottomline = wp->val2;
  1664.         f_y = cur_y = wp->val1*inc_y + wp->top_y;
  1665.         f_x = cur_x = X0;
  1666.         state = S_NORMAL;
  1667.         break;
  1668.       case 'm':
  1669.       {
  1670.         int i;
  1671.         for(i=0;i <= wp->valcnt;i++)
  1672.         {
  1673.           switch(wp->val[i])
  1674.           {
  1675.           case 0:  /* Exit Inverse */
  1676.             wp->inverse = 0;
  1677.             break;
  1678.           default:
  1679.             wp->inverse = 1;
  1680.           }
  1681.         }
  1682.         state = S_NORMAL;
  1683.         break;
  1684.       }
  1685.       default:
  1686.         state = S_NORMAL;
  1687.         break;
  1688.       }
  1689.     }  /* end switch on state */
  1690.     }
  1691.     if (scrolled >= MAXSCROLLED) 
  1692.     {
  1693.       if (wp->top_y != Y0) 
  1694.       {
  1695.         scrollup(wp, 0, ysiz, wp->top_y/inc_y);
  1696.         wp->top_y = Y0;
  1697.         f_y = cur_y = Y0 + (ysiz - 1) * inc_y;
  1698.       }
  1699.       w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  1700.       scrolled = 0;
  1701.     }
  1702.   }  /* end while loop for each character */
  1703.  
  1704.              /*
  1705.              * "scrolled" is true if you need to do a hard update, where multiple
  1706.              * lines may have changed.  This used to actually align the virtual
  1707.              * screen with the physical screen only when scrolled >= MAXSCROLLED, but
  1708.              * this meant that seven lines out of eight got hard updates for every
  1709.              * char when typing on a scrolling TTY.  So I align them every time.
  1710.              */
  1711.   if (scrolled) 
  1712.   {
  1713.     if (wp->top_y != Y0) 
  1714.     {
  1715.       scrollup(wp, 0, ysiz, wp->top_y/inc_y);
  1716.       cur_y -= (wp->top_y - Y0);
  1717.       wp->top_y = Y0;
  1718.     }
  1719.   }
  1720.   w_redraw(wp, FM_COPY, wp->x, wp->y, wp->w, wp->h);
  1721.   wp->cur_x = cur_x;
  1722.   wp->cur_y = cur_y;
  1723.   wp->state = state;
  1724.   w_flash(wp, 1);
  1725. }
  1726.  
  1727. void lineerase(wp, first, last)
  1728. register struct wi_str *wp;
  1729. int first, last;
  1730. {
  1731.   register short *p;
  1732.   register long *lp;
  1733.   long count;
  1734.   long linespace = wp->wi_mf.wwords*wp->font->inc_y;
  1735.  
  1736.   p = wp->wi_mf.ptr + first*linespace + Y0*wp->wi_mf.wwords - 1;
  1737.   count = (last-first+1)*linespace;
  1738.   lp = (long *)p;
  1739.   while (count > 7)
  1740.   {
  1741.     *lp++ = 0;
  1742.     *lp++ = 0;
  1743.     *lp++ = 0;
  1744.     *lp++ = 0;
  1745.     count -= 8;
  1746.   }
  1747.   p = (short *)lp;
  1748.   while (--count >= 0)
  1749.     *++p = 0;
  1750. }
  1751.  
  1752. void scrollup(wp, first, nlines, amount)
  1753. register struct wi_str *wp;
  1754. int first, nlines, amount;
  1755. {
  1756.   register short *p1, *p2;
  1757.   register long *lp1, *lp2;
  1758.   register long count;
  1759.   int linespace = wp->wi_mf.wwords*wp->font->inc_y;
  1760.  
  1761.   p1 = wp->wi_mf.ptr + first*linespace + Y0*wp->wi_mf.wwords;
  1762.   p2 = p1 + linespace * amount;
  1763.   count = (long)(nlines)*linespace;
  1764.   lp1 = (long *)p1;
  1765.   lp2 = (long *)p2;
  1766.   while (count > 15)
  1767.   {
  1768.     *lp1++ = *lp2++;
  1769.     *lp1++ = *lp2++;
  1770.     *lp1++ = *lp2++;
  1771.     *lp1++ = *lp2++;
  1772.     *lp1++ = *lp2++;
  1773.     *lp1++ = *lp2++;
  1774.     *lp1++ = *lp2++;
  1775.     *lp1++ = *lp2++;
  1776.     count -= 16;
  1777.   }
  1778.   p1 = (short *)lp1;
  1779.   p2 = (short *)lp2;
  1780.   while (--count >= 0)
  1781.     *(p1++) = *(p2++);
  1782.   count = linespace * amount;
  1783.   lp1 = (long *)p1;
  1784.   while (count > 7)
  1785.   {
  1786.     *lp1++ = 0;
  1787.     *lp1++ = 0;
  1788.     *lp1++ = 0;
  1789.     *lp1++ = 0;
  1790.     count -= 8;
  1791.   }
  1792.   p1 = (short *)lp1;
  1793.   while (--count >= 0)
  1794.     *(p1++) = 0;
  1795. }
  1796.  
  1797. void scrolldn(wp, first, nlines, amount)
  1798. register struct wi_str *wp;
  1799. int first, nlines, amount;
  1800. {
  1801.   register short *p1, *p2;
  1802.   register long *lp1, *lp2;
  1803.   register long count;
  1804.   long linespace = wp->wi_mf.wwords*wp->font->inc_y;
  1805.  
  1806.   p1 = wp->wi_mf.ptr + (nlines+first+amount)*linespace + Y0*wp->wi_mf.wwords;
  1807.  
  1808.   p2 = p1 - linespace * amount;
  1809.   count = (long)(nlines)*linespace;
  1810.   lp2 = (long *)p2;
  1811.   lp1 = (long *)p1;
  1812.   while (count > 15)
  1813.   {
  1814.     *--lp1 = *--lp2;
  1815.     *--lp1 = *--lp2;
  1816.     *--lp1 = *--lp2;
  1817.     *--lp1 = *--lp2;
  1818.     *--lp1 = *--lp2;
  1819.     *--lp1 = *--lp2;
  1820.     *--lp1 = *--lp2;
  1821.     *--lp1 = *--lp2;
  1822.     count -= 16;
  1823.   }
  1824.   p1 = (short *)lp1;
  1825.   p2 = (short *)lp2;
  1826.   while (--count >= 0)
  1827.     *--p1 = *--p2;
  1828.   count = linespace * amount;
  1829.   lp1 = (long *)p1;
  1830.   while (count > 7)
  1831.   {
  1832.     *--lp1 = 0L;
  1833.     *--lp1 = 0L;
  1834.     *--lp1 = 0L;
  1835.     *--lp1 = 0L;
  1836.     count -= 8;
  1837.   }
  1838.   p1 = (short *)lp1;
  1839.   while (--count >= 0)
  1840.     *--p1 = 0;
  1841. }
  1842. /* -------------------------------------------------------------------- */
  1843. /*       boolean rc_intersect( GRECT *r1, GRECT *r2 );                  */
  1844. /*                                                                      */
  1845. /*       Berechnung der Schnittfläche zweier Rechtecke.                 */
  1846. /*                                                                      */
  1847. /*       -> r1, r2               Pointer auf Rechteckstruktur.          */
  1848. /*                                                                      */
  1849. /*       <-                      TRUE  falls sich die Rechtecke         */
  1850. /*                                     schneiden,                       */
  1851. /*                               FALSE sonst.                           */
  1852. /* -------------------------------------------------------------------- */
  1853.  
  1854. int rc_intersect( GRECT *r1, GRECT *r2 )
  1855. {
  1856.   int x, y, w, h;
  1857.  
  1858.   x = max( r2->g_x, r1->g_x );
  1859.   y = max( r2->g_y, r1->g_y );
  1860.   w = min( r2->g_x + r2->g_w, r1->g_x + r1->g_w );
  1861.   h = min( r2->g_y + r2->g_h, r1->g_y + r1->g_h );
  1862.  
  1863.   r2->g_x = x;
  1864.   r2->g_y = y;
  1865.   r2->g_w = w - x;
  1866.   r2->g_h = h - y;
  1867.  
  1868.   return (((w > x) && (h > y) ) );
  1869. }
  1870.  
  1871. /*------------------------------*/
  1872. /*    vt100_reset        */
  1873. /*------------------------------*/
  1874. void vt100_reset (struct wi_str *wp)
  1875. {
  1876.   wp->repeat = 1;
  1877.   wp->curskey = 0;
  1878.   wp->keypad = 0;
  1879.   wp->topline = 0;
  1880.   wp->bottomline = 23;
  1881.   wp->colwidth = 0;
  1882.   wp->smooth = 0;
  1883.   wp->origmode = 0;
  1884.   wp->lfmode = 0;
  1885.   return;
  1886. }
  1887.  
  1888.